struct domain *d = current->domain;
struct vcpu *v;
+ if ( !is_hvm_domain(d) )
+ return -EINVAL;
+
/* Avoid deadlock if more than one vcpu tries this at the same time. */
if ( !spin_trylock(&d->hypercall_deadlock_mutex) )
return -EAGAIN;
long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
{
+ struct domain *curr_d = current->domain;
long rc = 0;
switch ( op )
if ( rc != 0 )
return rc;
+ rc = -EPERM;
+ if ( (curr_d != d) && !IS_PRIV_FOR(curr_d, d) )
+ goto param_fail;
+
rc = -EINVAL;
if ( !is_hvm_domain(d) )
goto param_fail;
rc = -EINVAL;
break;
case HVM_PARAM_IDENT_PT:
+ /* Not reflexive, as we must domain_pause(). */
rc = -EPERM;
- if ( !IS_PRIV(current->domain) )
+ if ( curr_d == d )
break;
rc = -EINVAL;
domctl_lock_release();
break;
case HVM_PARAM_DM_DOMAIN:
- /* Privileged domains only, as we must domain_pause(d). */
+ /* Not reflexive, as we must domain_pause(). */
rc = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
+ if ( curr_d == d )
break;
if ( a.value == DOMID_SELF )
- a.value = current->domain->domain_id;
+ a.value = curr_d->domain_id;
rc = 0;
domain_pause(d); /* safe to change per-vcpu xen_port */
domain_unpause(d);
break;
case HVM_PARAM_ACPI_S_STATE:
- /* Privileged domains only, as we must domain_pause(d). */
+ /* Not reflexive, as we must domain_pause(). */
rc = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
+ if ( curr_d == d )
break;
rc = 0;
if ( rc != 0 )
return rc;
+ rc = -EPERM;
+ if ( !IS_PRIV_FOR(curr_d, d) )
+ goto param_fail2;
+
rc = -EINVAL;
if ( !is_hvm_domain(d) )
goto param_fail2;
if ( rc != 0 )
return rc;
+ rc = -EPERM;
+ if ( !IS_PRIV_FOR(curr_d, d) )
+ goto param_fail3;
+
rc = -EINVAL;
if ( !is_hvm_domain(d) )
goto param_fail3;
if ( rc != 0 )
return rc;
+ rc = -EPERM;
+ if ( !IS_PRIV_FOR(curr_d, d) )
+ goto param_fail4;
+
rc = -EINVAL;
if ( !is_hvm_domain(d) )
goto param_fail4;